package me.magicall.myblog.util;

import java.util.concurrent.ConcurrentHashMap;

import me.magicall.db.dao.Dao;
import me.magicall.db.meta.CachedTableMetaAccessor;
import me.magicall.db.meta.TableMetaAccessor;
import me.magicall.db.model.BaseModel.NbBean;
import me.magicall.db.springjdbc.NbBeanDaoImpl;
import me.magicall.db.springjdbc.SpringJdbcTableMetaAccessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class DaoFactory implements ApplicationContextAware {
	@Autowired
	private SimpleJdbcTemplate jdbc;
	@Autowired
	private ModelEnumHolder modelEnumHolder;

	private TableMetaAccessor tableMetaAccessor;

	private final ConcurrentHashMap<String, Dao<?>> map = new ConcurrentHashMap<String, Dao<?>>();

	public Dao<NbBean<?>> getNbBeanDao(final String enumName) {
		return getNbBeanDao(modelEnumHolder.getEnumClass(enumName));
	}

	@SuppressWarnings("unchecked")
	public Dao<NbBean<?>> getNbBeanDao(final Class<? extends Enum<?>> enumClass) {
		Dao<NbBean<?>> dao = (Dao<NbBean<?>>) map.get(enumClass.getName());
		if (dao == null) {
			dao = new NbBeanDaoImpl(jdbc, tableMetaAccessor, enumClass);
			map.putIfAbsent(enumClass.getName(), dao);
		}
		return dao;
	}

	public SimpleJdbcTemplate getJdbc() {
		return jdbc;
	}

	public void setJdbc(final SimpleJdbcTemplate jdbc) {
		this.jdbc = jdbc;
	}

	public TableMetaAccessor getTableMetaBuilder() {
		return tableMetaAccessor;
	}

	public void setTableMetaBuilder(final TableMetaAccessor tableMetaBuilder) {
		this.tableMetaAccessor = tableMetaBuilder;
	}

	@Override
	public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
		tableMetaAccessor = new CachedTableMetaAccessor(applicationContext.getBean(SpringJdbcTableMetaAccessor.class));
	}

//	@Override
//	public boolean containsBeanDefinition(final String beanName) {
//		return map.containsKey(beanName);
//	}
//
//	@Override
//	public <A extends Annotation> A findAnnotationOnBean(final String beanName, final Class<A> annotationType) {
//		return AnnotationUtils.findAnnotation(getType(beanName), annotationType);
//	}
//
//	@Override
//	public int getBeanDefinitionCount() {
//		return map.size();
//	}
//
//	@Override
//	public String[] getBeanDefinitionNames() {
//		return StringUtils.toStringArray(map.keySet());
//	}
//
//	@SuppressWarnings("unchecked")
//	@Override
//	public String[] getBeanNamesForType(final Class type) {
//		return getBeanNamesForType(type, true, true);
//	}
//
//	@SuppressWarnings("unchecked")
//	@Override
//	public String[] getBeanNamesForType(final Class type, final boolean includeNonSingletons, final boolean allowEagerInit) {
//		// TODO Auto-generated method stub
//		return null;
//	}
//
//	@Override
//	public <T> Map<String, T> getBeansOfType(final Class<T> type) throws BeansException {
//		return getBeansOfType(type, true, true);
//	}
//
//	@Override
//	public <T> Map<String, T> getBeansOfType(final Class<T> type, final boolean includeNonSingletons, final boolean allowEagerInit) throws BeansException {
//		// TODO Auto-generated method stub
//		return null;
//	}
//
//	@Override
//	public Map<String, Object> getBeansWithAnnotation(final Class<? extends Annotation> annotationType) throws BeansException {
//		final Map<String, Object> results = new LinkedHashMap<String, Object>();
//		for (final String beanName : map.keySet()) {
//			if (findAnnotationOnBean(beanName, annotationType) != null) {
//				results.put(beanName, getBean(beanName));
//			}
//		}
//		return results;
//	}
//
//	@Override
//	public boolean containsBean(final String name) {
//		// TODO Auto-generated method stub
//		return false;
//	}
//
//	@Override
//	public String[] getAliases(final String name) {
//		return Utils.STR.emptyArray();
//	}
//
//	@Override
//	public Object getBean(final String name) throws BeansException {
//		// TODO Auto-generated method stub
//		return null;
//	}
//
//	@Override
//	public <T> T getBean(final Class<T> requiredType) throws BeansException {
//		// TODO Auto-generated method stub
//		return null;
//	}
//
//	@Override
//	public <T> T getBean(final String name, final Class<T> requiredType) throws BeansException {
//		// TODO Auto-generated method stub
//		return null;
//	}
//
//	@Override
//	public Object getBean(final String name, final Object... args) throws BeansException {
//		// TODO Auto-generated method stub
//		return null;
//	}
//
//	@Override
//	public Class<?> getType(final String name) throws NoSuchBeanDefinitionException {
//		return modelEnumHolder.getEnumClass(name);
//	}
//
//	@Override
//	public boolean isPrototype(final String name) throws NoSuchBeanDefinitionException {
//		return false;
//	}
//
//	@Override
//	public boolean isSingleton(final String name) throws NoSuchBeanDefinitionException {
//		return true;
//	}
//
//	@SuppressWarnings("unchecked")
//	@Override
//	public boolean isTypeMatch(final String name, final Class targetType) throws NoSuchBeanDefinitionException {
//		// TODO Auto-generated method stub
//		return false;
//	}
}
